package org.boge.sharpdoc.controller;

import com.github.pagehelper.PageInfo;
import org.apache.commons.io.FileUtils;
import org.boge.sharpdoc.config.Settings;
import org.boge.sharpdoc.bean.*;
import org.boge.sharpdoc.service.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.*;

@Controller
@RequestMapping("document")
public class DocumentController {
    @Autowired
    private DocumentService documentService;
    @Autowired
    private HttpSession session;
    @Autowired
    private DocCollectService docCollectService;
    @Autowired
    private CustomerService customerService;
    @Autowired
    private DownloadHistoryService downloadHistoryService;
    @Autowired
    private DocGroupService docGroupService;
    @Autowired
    private Settings settings;

    @GetMapping("uploadDocPage")
    public String uploadDocPage() {
        return "document/uploadDoc";
    }

    @PostMapping("uploadDoc")
    @ResponseBody
    public LayuiReturnData uploadDoc(MultipartFile file, Document document) throws IOException {
        Customer customer = (Customer) session.getAttribute("current_customer");
        document.setUploaduser(customer);
        // 获取后缀名
        String oriname = file.getOriginalFilename();
        document.setSuffixicon(new DocIcon(oriname.substring(oriname.lastIndexOf('.') + 1)));
        // 保存文件
        String storedname = UUID.randomUUID().toString();
        document.setStoredname(storedname);
        File targetDir = new File(settings.getDocsDir(), storedname);
        targetDir.mkdirs();
        file.transferTo(new File(targetDir, storedname));
        document.setFilesize(file.getSize());
        documentService.uploadDocument(document);
        return new LayuiReturnData(0);
    }

    @GetMapping("documentDetail")
    public String documentDetail(Integer docid, Model model) {
        Customer customer = (Customer) session.getAttribute("current_customer");
        documentService.updateHot(docid);
        model.addAttribute("d_document", documentService.findDocById(docid));
        model.addAttribute("iscollected", customer != null && docCollectService.isCollected(customer.getPhone(), docid));
        return "document/show";
    }

    @ResponseBody
    @GetMapping("getSVG")
    public byte[] getSVG(String stname, Integer pageId) throws IOException {
        File svgFile = new File(new File(new File(settings.getDocsDir(), stname), "svgs"), String.format("%05d", pageId) + "_" + stname + ".svg");
        if (svgFile.exists())
            return FileUtils.readFileToByteArray(svgFile);
        else
            return null;
    }

    @RequestMapping(value = "searchDoc")
    public String searchDoc(
            @RequestParam(defaultValue = "-1") Integer groupid,
            @RequestParam(defaultValue = "") String keyword,
            @RequestParam(defaultValue = "0") Integer order,
            @RequestParam(defaultValue = "1") Integer index,
            @RequestParam(defaultValue = "10") Integer pageSize,
            Model model) {
        PageInfo<Document> pageInfo = null;
        if (groupid.equals(-1))
            pageInfo = documentService.searchDocs(keyword, order, index, pageSize);
        else {
            List<DocGroup> groups = docGroupService.getAllGroupChildren(docGroupService.findById(groupid));
            pageInfo = documentService.searchDocs(groups, keyword, order, index, pageSize);
        }
        model.addAttribute("docpageinfo", pageInfo);
        Map<String, Object> searchInfos = new HashMap<>();
        searchInfos.put("groupid", groupid);
        searchInfos.put("keyword", keyword);
        searchInfos.put("order", order);
        model.addAttribute("searchInfos", searchInfos);
        return "document/result";
    }

    @GetMapping("downloadDoc")
    public void downloadDoc(Integer docid, Integer dlCheckCode, HttpServletResponse response) throws IOException {
        //核对校验码
        Integer s_code = (Integer) session.getAttribute("dlCheckCode");
        if (s_code == null || !s_code.equals(dlCheckCode))
            return;
        //下载次数加一
        documentService.updateDownloadTimes(docid);
        Document document = documentService.findDocById(docid);
        File storedFile = new File(new File(settings.getDocsDir(), document.getStoredname()), document.getStoredname());
        response.setContentType("application/octet-stream");
        ServletOutputStream os = response.getOutputStream();
        BufferedInputStream bis = new BufferedInputStream(new FileInputStream(storedFile));
        byte[] slice = new byte[1024];
        int length = 0;
        while ((length = bis.read(slice)) > 0) {
            os.write(slice, 0, length);
        }
        os.flush();
        os.close();
        bis.close();
    }

    @GetMapping("admin/failedPage")
    public String failedPage() {
        return "admin/document/failed";
    }

    @GetMapping("admin/forbiddenPage")
    public String forbiddenPage() {
        return "admin/document/forbidden";
    }

    @GetMapping("admin/needCheckPage")
    public String needCheckPage() {
        return "admin/document/needCheck";
    }

    @GetMapping("admin/passedPage")
    public String passedPage() {
        return "admin/document/passed";
    }

    @PostMapping("admin/getWithStatus")
    @ResponseBody
    public LayuiReturnData getWithStatus(String status, Integer index, Integer pageSize) {
        PageInfo<Document> pageInfo = documentService.getAllDocumentsByStatusWithPage(status, index, pageSize);
        List<Document> documents = pageInfo.getList();
        for (Document d : documents) {
            d.getDocGroup().setChildren(null);
            d.setCommentList(new ArrayList<>(d.getCommentList().size()));
            d.getUploaduser().setUploadeddoc(null);
            d.getUploaduser().setCommentList(null);
        }
        return new LayuiReturnData(0, true, "数据查询成功！", (int) pageInfo.getTotal(), documents);
    }

    @GetMapping("admin/docPreviewPage")
    public String docPreview(Integer docid, Model model) {
        model.addAttribute("d_document", documentService.findDocById(docid));
        return "admin/document/preview";
    }

    @PostMapping("admin/changeDocStatus")
    @ResponseBody
    public LayuiReturnData changeDocStatus(Integer docid, String status) {
        documentService.changeStatus(docid, status);
        if (status.equals("已通过")) {
            //给上传者加2积分
            Document document = documentService.findDocById(docid);
            customerService.addIntegral(document);
        }
        //更新审核文档的管理员字段
        documentService.updateAuditor(docid, ((Administrator) session.getAttribute("current_administrator")).getAdminid());
        return new LayuiReturnData(0);
    }

    @PostMapping("dlJudge")
    @ResponseBody
    public LayuiReturnData dlJudge(Integer docid) {
        Customer customer = (Customer) session.getAttribute("current_customer");
        Document document = documentService.findDocById(docid);
        String msg = "";
        if (document.getUploaduser().getPhone().equals(customer.getPhone()))
            msg += "您上传了此文档，本次下载免费，感谢您对本站的支持。";
        else if (downloadHistoryService.findByUidAndDocid(customer.getPhone(), docid).size() > 0)
            msg += "您曾经下载过此文件，本次下载免费。";
        else if (customer.getIntegral() >= document.getNeededintegral()) {
            msg += "本次下载扣除" + document.getNeededintegral() + "积分。";
            //扣除积分
            customer = customerService.decIntegral(customer, document.getNeededintegral());
            //更新session中的信息
            session.setAttribute("current_customer", customer);
        } else {
            // 积分不足
            return new LayuiReturnData(0, false, "您的积分不足，无法下载此文件！");
        }
        //为防止用户直接通过url下载文件，此处生成下载校验码
        Integer num = new Random().nextInt(1000000);
        session.setAttribute("dlCheckCode", num);
        //添加下载记录
        downloadHistoryService.addItem(customer.getPhone(), docid);
        return new LayuiReturnData(0, true, msg, num);
    }
}